<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 垃圾回收 指的是没有用的东西应被清理
        // 内存空间有限 不可能给我们无限使用内存 于是就得有回收机制 

        // 定义了一个空对象 将地址赋值给obj变量
        // var obj = {};
        // 现在让obj变量保存1去了 对象就没有东西保存 从代码的角度来说 也没有任何方式能够访问这个对象了 那么这个对象就是个"垃圾"
        // obj = 1;
        // 就应该被回收 我们的浏览器会自动执行垃圾回收机制 


        // ES12中新增了一个FinalizationRegistry构造函数 可以初始化一个监听对象 监听另一个对象被回收
        // var obj = {"name": "小明"};
        // var registry = new FinalizationRegistry(heldValue => {
        //     console.log(heldValue);
        // });
        // registry.register(obj, "小明对象被回收了")

        // var obj1 = {"name": "小红"}
        // registry.register(obj1, "小红对象被回收了")


        // obj = 1;

        // 垃圾回收机制有2种： 引用计数  标记清除
        // 引用计数：每有一个变量或者属性引用了这个对象 就会给这个对象+1  每有一个变量或者属性不再引用这个对象 就-1 当为0的时候将等待被回收
        // var a = {};  // 此时对象被变量a引用 所以计数为1 
        // var b = a; // 此时对象被变量b引用 所以计数为2
        // a = 1; // 此时a不再保存对象 b还保存着 计数为1
        // b = 1 // 此时b也不再保存对象 计数为0
        // 此时这个对象将会被回收


        // 这种引用计数有问题：循环引用
        // var a = {};
        // var b = {};
        // a.o = b;
        // b.o = a;
      
        // a = 1;
        // b = 1;
        // 此时a保存1 b保存1 通过程序无法访问到上面的两个对象但是这两个对象依然引用计数为1 因为互相引用 
        // 两个对象已经没有用了 但是却无法被回收 这种现象叫做内存泄漏



        // 标记清除  也是一种垃圾回收机制 它有一个"根"的概念 就是全局作用域
        // 通过根沿着引用关系向外寻找每找到一个就打标记 打完标记继续向外寻找继续打标记
        // 直到再也找不到了为止 
        // 此时开始回收 没有打标记的会被回收 


    </script>
</body>

</html>